/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						       bound_handler.h

	$Header: /game/bound_handler.h $

	$NoKeywords: $

 ************************************************************************/

#ifndef BOUND_HANDLER_H_INCLUDED
#define BOUND_HANDLER_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "handler.h"
// --------------------------------------------------------------------------
// typical usage:
//
// class t_client
// {
// public:
//     void click_2( t_button* );
// };
//
//     button->set_handler( bound_handler( client, &t_client::click_2 ) );
//

// ---------------------------------------------------------
// callback which takes an object and a pointer to member function
// ----------------------------------------------------------
template <class t_client>
class t_bound_handler : public t_handler_base
{
public:
	typedef void ( t_client::* t_function )();

	t_bound_handler( t_client& client, t_function function )
		           : m_client( client ), m_function( function )
	{
	}

	virtual void operator()()
	{
		( m_client.*m_function )();
	}

private:
	t_client&  m_client;
	t_function m_function;
};

// ---------------------------------------------------------
// callback which takes an object and a pointer to member function
// ----------------------------------------------------------
template < typename t_client >
class t_const_bound_handler : public t_handler_base
{
public:
	// Types
	typedef void ( t_client::* t_function )() const;

	// Constructor
	t_const_bound_handler( t_client const& client, t_function function )
   	                     : m_client( client ), m_function( function )
	{
	}

	// Operator
	virtual void operator()() 
	{
		( m_client.*m_function )(); 
	}

private:
	// Data members
	t_client const&	m_client;
	t_function	    m_function;
};


// ---------------------------------------------------------
// callback which takes an object and a pointer to member function
// ----------------------------------------------------------
template <class t_client, class type>
class t_bound_handler_1 : public t_handler_base_1<type>
{
public:
	typedef void ( t_client::* t_function )( type );

	t_bound_handler_1( t_client& client, t_function function )
		           : m_client( client ), m_function( function )
	{
	}

	virtual void operator()( type arg )
	{
		( m_client.*m_function )(arg);
	}

private:
	t_client&  m_client;
	t_function m_function;
};

// ---------------------------------------------------------
// callback which takes an object and a pointer to member function
// ----------------------------------------------------------
template < typename t_client, class type >
class t_const_bound_handler_1 : public t_handler_base_1<type>
{
public:
	// Types
	typedef void ( t_client::* t_function )( type ) const;

	// Constructor
	t_const_bound_handler_1( t_client const& client, t_function function )
   	                         : m_client( client ), m_function( function )
	{
	}

	// Operator
	virtual void operator()(type arg) 
	{
		( m_client.*m_function )(arg);
	}

private:
	// Data members
	t_client const&	m_client;
	t_function	    m_function;
};


// ---------------------------------------------------------
// callback which takes an object and a pointer to member function
// ----------------------------------------------------------
template <class t_client, class type_1, class type_2 >
class t_bound_handler_2 : public t_handler_base_2<type_1, type_2>
{
public:
	typedef void ( t_client::* t_function )( type_1, type_2 );

	t_bound_handler_2( t_client& client, t_function function )
		           : m_client( client ), m_function( function )
	{
	}

	virtual void operator()( type_1 arg_1, type_2 arg_2 )
	{
		( m_client.*m_function )(arg_1, arg_2);
	}

private:
	t_client&  m_client;
	t_function m_function;
};

// ---------------------------------------------------------
// callback which takes an object and a pointer to member function
// ----------------------------------------------------------
template < typename t_client, class type_1, class type_2 >
class t_const_bound_handler_2 : public t_handler_base_2<type_1, type_2>
{
public:
	// Types
	typedef void ( t_client::* t_function )( type_1, type_2 ) const;

	// Constructor
	t_const_bound_handler_2( t_client const& client, t_function function )
   	                         : m_client( client ), m_function( function )
	{
	}

	// Operator
	virtual void operator()(type_1 arg_1, type_2 arg_2) 
	{
		( m_client.*m_function )(arg_1, arg_2);
	}

private:
	// Data members
	t_client const&	m_client;
	t_function	    m_function;
};


// ---------------------------------------------------------
// callback which takes an object and a pointer to member function
// ----------------------------------------------------------
template <class t_client, class type_1, class type_2, class type_3 >
class t_bound_handler_3 : public t_handler_base_3<type_1, type_2, type_3>
{
public:
	typedef void ( t_client::* t_function )( type_1, type_2, type_3 );

	t_bound_handler_3( t_client& client, t_function function )
		           : m_client( client ), m_function( function )
	{
	}

	virtual void operator()( type_1 arg_1, type_2 arg_2, type_3 arg_3 )
	{
		( m_client.*m_function )(arg_1, arg_2, arg_3);
	}

private:
	t_client&  m_client;
	t_function m_function;
};

// ---------------------------------------------------------
// callback which takes an object and a pointer to member function
// ----------------------------------------------------------
template < class t_client, class type_1, class type_2, class type_3 >
class t_const_bound_handler_3 : public t_handler_base_3<type_1, type_2, type_3>
{
public:
	// Types
	typedef void ( t_client::* t_function )( type_1, type_2, type_3 ) const;

	// Constructor
	t_const_bound_handler_3( t_client const& client, t_function function )
   	                         : m_client( client ), m_function( function )
	{
	}

	// Operator
	virtual void operator()(type_1 arg_1, type_2 arg_2, type_3 arg_3) 
	{
		( m_client.*m_function )(arg_1, arg_2, arg_3);
	}
private:
	// Data members
	t_client const&	m_client;
	t_function	    m_function;
};


// ---------------------------------------------------------
// convenience function for constructing bound handlers.
// usage of all verieties is:
//    bound_handler( client, &t_client::function );
// ---------------------------------------------------------
template < typename t_client >
inline t_handler bound_handler( t_client& client, void (t_client::*function)() )
{
	return new t_bound_handler< t_client >( client, function );
}

template < typename t_client >
inline t_handler bound_handler( t_client const& client, void (t_client::*function)() )
{
	return new t_const_bound_handler< t_client >( client, function );
}

// ---------------------------------------------------------
// convenience function for constructing bound handlers.
// ---------------------------------------------------------
template < typename t_client, class type >
inline t_handler_1<type> bound_handler( t_client& client, void (t_client::*function)(type) )
{
	return new t_bound_handler_1< t_client, type >( client, function );
}

template < typename t_client, class type >
inline t_handler_1<type> bound_handler( t_client const& client, 
											  void (t_client::*function)(type) )
{
	return new t_const_bound_handler_1< t_client, type >( client, function );
}

// ---------------------------------------------------------
// convenience function for constructing bound handlers.
// ---------------------------------------------------------
template < typename t_client, class type_1, class type_2 >
inline t_handler_2<type_1, type_2> bound_handler( t_client& client, 
												  void (t_client::*function)(type_1, type_2) )
{
	return new t_bound_handler_2< t_client, type_1, type_2 >( client, function );
}

template < typename t_client, class type_1, class type_2 >
inline t_handler_2<type_1, type_2> bound_handler( t_client const& client, 
										          void (t_client::*function)(type_1, type_2) )
{
	return new t_const_bound_handler_2< t_client, type_1, type_2 >( client, function );
}

// ---------------------------------------------------------
// convenience function for constructing bound handlers.
// ---------------------------------------------------------
template < typename t_client, class type_1, class type_2, class type_3 >
inline t_handler_3<type_1, type_2, type_3> bound_handler( t_client& client, 
									void (t_client::*function)(type_1, type_2, type_3) )
{
	return new t_bound_handler_3< t_client, type_1, type_2, type_3 >( client, function );
}

template < typename t_client, class type_1, class type_2, class type_3 >
inline t_handler_3<type_1, type_2, type_3> bound_handler( t_client const& client, 
										void (t_client::*function)(type_1, type_2, type_3) )
{
	return new t_const_bound_handler_3< t_client, type_1, type_2, type_3 >( client, function );
}

#endif // BOUND_HANDLER_H_INCLUDED
